home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / winprogs / wschesb1 / src / wscomms.c < prev   
Encoding:
C/C++ Source or Header  |  1994-03-16  |  26.4 KB  |  911 lines

  1. /*
  2.   C source for Winsock Chess
  3.   
  4.   Revision 1994-03-15
  5.   Modified by Donald Munro for use as a 2 player chess game over a 
  6.   WINSOCK layer on a TCP (or other WinSock supporting) network.
  7.   Source code and make files for MS Visual C/C++ V1.00/1.50.
  8.   February/March 1994
  9.   All GNU copyright and distribution conditions as described below and in the
  10.   file COPYING also apply to WinSock Chess.
  11.   This module is Winsock Chess specific.
  12.   
  13.   C source for GNU CHESS
  14.  
  15.   Revision: 1990-09-30
  16.   Modified by Daryl Baker for use in MS WINDOWS environment
  17.   
  18.   Revision 1994-03-15
  19.   Modified by Donald Munro for use as a 2 player chess game over a 
  20.   communications link viz WINSOCK or other.
  21.   Source code and make files for MS Visual C++ V1.00/1.50
  22.   Conversion to usage of message crackers for easy conversion to win32
  23.   February/March 1994
  24.  
  25.   Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  26.   Copyright (c) 1988, 1989, 1990  John Stanback
  27.  
  28.   This file is part of CHESS.
  29.  
  30.   CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  31.   WARRANTY.  No author or distributor accepts responsibility to anyone for
  32.   the consequences of using it or for whether it serves any particular
  33.   purpose or works at all, unless he says so in writing.  Refer to the CHESS
  34.   General Public License for full details.
  35.  
  36.   Everyone is granted permission to copy, modify and redistribute CHESS, but
  37.   only under the conditions described in the CHESS General Public License.
  38.   A copy of this license is supposed to have been given to you along with
  39.   CHESS so you can know your rights and responsibilities.  It should be in a
  40.   file named COPYING.  Among other things, the copyright notice and this
  41.   notice must be preserved on all copies.
  42. */
  43.  
  44. #define NOATOM         
  45. #define NOCREATESTRUCT
  46. #define NOFONT
  47. #define NOREGION
  48. #define NOSOUND
  49. #define NOWH
  50. #define NOKANJI
  51.  
  52. #define STRICT 
  53. #include <windows.h>         
  54. #include <windowsx.h>
  55. #include <commdlg.h>
  56. #include <string.h>  
  57. #include <memory.h>
  58. #include <stdarg.h>
  59.  
  60. #include "resource.h"
  61. #include "winsock.h"
  62. #include "gnuchess.h"
  63. #include "defs.h"    
  64. #include "chess.h"
  65.  
  66. #define DESIRED_WINSOCK_VERSION         0x0101  
  67. #define MINIMUM_WINSOCK_VERSION         0x0001 
  68. #define WSCHESS_PORT                    1985
  69.  
  70. extern HWND hwndHostDlg,hwndMain;               
  71. extern BOOL bHost,bWaiting,bMoveReady,bConnected;
  72. extern HINSTANCE hInst;
  73. extern MoveInfo moveinfo;
  74. extern char szSockDesc[45];
  75. extern HWND hwndHostDlg,hwndMain;               
  76. extern WORD wPacketSize;
  77. extern void (*SendMove)(WORD);         
  78. extern int User_Move;    
  79.  
  80. void WaitForSocket(void);
  81. struct sockaddr_in client_addr;
  82. SOCKET socketListen,socketServer,socketClient;
  83. WORD cbSent,cbReceived;;
  84. short oldTCmoves,oldTCminutes;
  85.  
  86. int MsgBox( HWND  hwndParent,
  87.             UINT  fuType,
  88.             LPSTR pszFormat,
  89.             ... )
  90. //----------------------------            
  91. {
  92.     char    szOutput[512];
  93.     va_list ArgList;
  94.  
  95.     va_start( ArgList, pszFormat );
  96.     wvsprintf( szOutput, pszFormat, ArgList );
  97.     va_end( ArgList );
  98.  
  99.     return MessageBox( hwndParent, szOutput,"WsChess", fuType );
  100.  
  101. }  
  102.  
  103.  
  104. LPSTR SocketErrorMsg(int nSockerr)
  105. //-----------------------------------
  106. {
  107.     switch( nSockerr )
  108.     {
  109.     case WSAENAMETOOLONG :
  110.         return "Name too long";
  111.  
  112.     case WSANOTINITIALISED :
  113.         return "Not initialized";
  114.     
  115.     case WSAENETDOWN :
  116.         return "Network subsystem down";
  117.     
  118.     case WSASYSNOTREADY :
  119.         return "System not ready";
  120.  
  121.     case WSAVERNOTSUPPORTED :
  122.         return "Version is not supported";
  123.  
  124.     case WSAESHUTDOWN :
  125.         return "Can't send after socket shutdown";
  126.  
  127.     case WSAEINTR :
  128.         return "Interrupted system call";
  129.  
  130.     case WSAHOST_NOT_FOUND :
  131.         return "Host not found";
  132.  
  133.     case WSATRY_AGAIN :
  134.         return "Try again";
  135.  
  136.     case WSANO_RECOVERY :
  137.         return "Non-recoverable error";
  138.  
  139.     case WSANO_DATA :
  140.         return "No data record available";
  141.  
  142.     case WSAEBADF :
  143.         return "Bad file number";
  144.  
  145.     case WSAEWOULDBLOCK :
  146.         return "Operation would block";
  147.  
  148.     case WSAEINPROGRESS :
  149.         return "Operation now in progress";
  150.  
  151.     case WSAEALREADY :
  152.         return "Operation already in progress";
  153.  
  154.     case WSAEFAULT :
  155.         return "Bad address";
  156.  
  157.     case WSAEDESTADDRREQ :
  158.         return "Destination address required";
  159.  
  160.     case WSAEMSGSIZE :
  161.         return "Message too long";
  162.  
  163.     case WSAEPFNOSUPPORT :
  164.         return "Protocol family not supported";
  165.  
  166.     case WSAENOTEMPTY :
  167.         return "Directory not empty";
  168.  
  169.     case WSAEPROCLIM :
  170.         return "EPROCLIM returned";
  171.  
  172.     case WSAEUSERS :
  173.         return "EUSERS returned";
  174.  
  175.     case WSAEDQUOT :
  176.         return "Disk quota exceeded";
  177.  
  178.     case WSAESTALE :
  179.         return "ESTALE returned";
  180.  
  181.     case WSAEINVAL :
  182.         return "Invalid argument";
  183.  
  184.     case WSAEMFILE :
  185.         return "Too many open files";
  186.  
  187.     case WSAEACCES :
  188.         return "Access denied";
  189.  
  190.     case WSAELOOP :
  191.         return "Too many levels of symbolic links";
  192.  
  193.     case WSAEREMOTE :
  194.         return "The object is remote";
  195.  
  196.     case WSAENOTSOCK :
  197.         return "Socket operation on non-socket";
  198.  
  199.     case WSAEADDRNOTAVAIL :
  200.         return "Can't assign requested address";
  201.  
  202.     case WSAEADDRINUSE :
  203.         return "Address already in use";
  204.  
  205.     case WSAEAFNOSUPPORT :
  206.         return "Address family not supported by protocol family";
  207.  
  208.     case WSAESOCKTNOSUPPORT :
  209.         return "Socket type not supported";
  210.  
  211.     case WSAEPROTONOSUPPORT :
  212.         return "Protocol not supported";
  213.  
  214.     case WSAENOBUFS :
  215.         return "No buffer space is supported";
  216.  
  217.     case WSAETIMEDOUT :
  218.         return "Connection timed out";
  219.  
  220.     case WSAEISCONN :
  221.         return "Socket is already connected";
  222.  
  223.     case WSAENOTCONN :
  224.         return "Socket is not connected";
  225.  
  226.     case WSAENOPROTOOPT :
  227.         return "Bad protocol option";
  228.  
  229.     case WSAECONNRESET :
  230.         return "Connection reset by peer";
  231.  
  232.     case WSAECONNABORTED :
  233.         return "Software caused connection abort";
  234.  
  235.     case WSAENETRESET :
  236.         return "Network was reset";
  237.  
  238.     case WSAECONNREFUSED :
  239.         return "Connection refused";
  240.  
  241.     case WSAEHOSTDOWN :
  242.         return "Host is down";
  243.  
  244.     case WSAEHOSTUNREACH :
  245.         return "Host is unreachable";
  246.  
  247.     case WSAEPROTOTYPE :
  248.         return "Protocol is wrong type for socket";
  249.  
  250.     case WSAEOPNOTSUPP :
  251.         return "Operation not supported on socket";
  252.  
  253.     case WSAENETUNREACH :
  254.         return "ICMP network unreachable";
  255.  
  256.     case WSAETOOMANYREFS :
  257.         return "Too many references";
  258.  
  259.     default :
  260.         return "Unknown";
  261.     }
  262. }
  263.  
  264.  
  265. void DestroySocket(SOCKET socket)
  266. //-------------------------------
  267. { LINGER linger;
  268.  
  269.   if (socket == INVALID_SOCKET)
  270.      return;
  271.  
  272.   // Hard close
  273.   linger.l_onoff  = TRUE;
  274.   linger.l_linger = 0;
  275.   setsockopt(socket,SOL_SOCKET,SO_LINGER,(char FAR *)&linger,sizeof(linger));
  276.   closesocket(socket);
  277. }  
  278.  
  279. //Blocking recv
  280. int BlockReceive(SOCKET socket,LPSTR lpszBuf,WORD wLen)
  281. //------------------------------------------------
  282. { WORD cbReceived;
  283.  
  284.   do
  285.     { cbReceived = recv(socket,lpszBuf,wLen,0);
  286.       if (cbReceived == SOCKET_ERROR) return WSAGetLastError();
  287.       lpszBuf += cbReceived;
  288.       wLen    -= cbReceived;
  289.     } while (wLen > 0);
  290.   *lpszBuf = 0;  
  291.   return 0;  
  292. }      
  293.  
  294. //Blocking send
  295. int BlockSend(SOCKET socket,LPSTR lpsBuf,WORD wLen)
  296. //------------------------------------------------
  297. { WORD cbSent;
  298.  
  299.   do
  300.     { cbSent = send(socket,lpsBuf,wLen,0);
  301.       if (cbSent == SOCKET_ERROR) return WSAGetLastError();
  302.       lpsBuf += cbSent;
  303.       wLen   -= cbSent;
  304.     } while (wLen > 0);
  305.   return 0;  
  306. }      
  307.  
  308. BOOL InitialiseWS(void)
  309. //---------------------
  310. { WSADATA wsadata;
  311.   int nSockerr;
  312.   
  313.   nSockerr = WSAStartup( DESIRED_WINSOCK_VERSION, &wsadata );
  314.  
  315.   if( nSockerr != 0 )
  316.     {
  317.         MsgBox( NULL,
  318.                 MB_ICONSTOP | MB_OK,
  319.                 "Cannot initialize WinSock, error %d: %s",
  320.                 nSockerr,
  321.                 SocketErrorMsg(nSockerr));
  322.         return FALSE;
  323.     }
  324.  
  325.     if( wsadata.wVersion < MINIMUM_WINSOCK_VERSION )
  326.     {
  327.         MsgBox( NULL,
  328.                 MB_ICONSTOP | MB_OK,
  329.                 "Windows Sockets version %02X.%02X, Version %02X.%02X Required",
  330.                 LOBYTE(wsadata.wVersion),
  331.                 HIBYTE(wsadata.wVersion),
  332.                 LOBYTE(MINIMUM_WINSOCK_VERSION),
  333.                 HIBYTE(MINIMUM_WINSOCK_VERSION) );
  334.         WSACleanup();
  335.         return FALSE;
  336.     }
  337.   strncpy(szSockDesc,wsadata.szDescription,40);
  338.   szSockDesc[40] = 0;
  339.   return TRUE;  
  340. }    
  341.  
  342. BOOL ServerStartWS(void)
  343. //----------------------
  344. { struct sockaddr_in srv_addr;
  345.  
  346.   socketListen = socket(AF_INET,SOCK_STREAM,0);
  347.   if (socketListen == INVALID_SOCKET)
  348.     { MsgBox( NULL,
  349.               MB_ICONSTOP | MB_OK,
  350.               "Winsock Error %s : Could not create server socket",
  351.               SocketErrorMsg(WSAGetLastError()));
  352.       WSACleanup();
  353.       return FALSE;
  354.     }
  355.   
  356.   srv_addr.sin_family      = AF_INET;
  357.   srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  358.   srv_addr.sin_port        = htons(WSCHESS_PORT);
  359.   
  360.   if (bind(socketListen,(LPSOCKADDR)&srv_addr,sizeof(srv_addr)) == SOCKET_ERROR)
  361.     { MsgBox( NULL,
  362.               MB_ICONSTOP | MB_OK,
  363.               "Winsock Error %s : Could not bind server socket",
  364.               SocketErrorMsg(WSAGetLastError()));
  365.       WSACleanup();
  366.       return FALSE;
  367.     }
  368.     
  369.   if (listen(socketListen,1) == SOCKET_ERROR)
  370.     { MsgBox( NULL,
  371.               MB_ICONSTOP | MB_OK,
  372.               "Winsock Error %s : Could not bind server socket",
  373.               SocketErrorMsg(WSAGetLastError()));
  374.       WSACleanup();
  375.       return FALSE;
  376.     }
  377.   if(WSAAsyncSelect(socketListen,hwndMain,WM_SOCKET,FD_ACCEPT) != 0)
  378.     { MsgBox( NULL,
  379.               MB_ICONSTOP | MB_OK,
  380.               "Winsock Error %s : Could not start async listener",
  381.               SocketErrorMsg(WSAGetLastError()));
  382.       WSACleanup();
  383.       return FALSE;
  384.     }                  
  385.   
  386.   return TRUE;
  387. }    
  388.  
  389. BOOL ClientStartWS(LPCSTR lpszServerIPAddr)
  390. //----------------------------------------
  391. { struct sockaddr_in srv_addr;
  392.   char szIpAddr[60];
  393.   LPHOSTENT lphostent;   
  394.   unsigned long ulIpAddr;        // WIN32 change to int/WORD if same as UNIX!
  395.   unsigned long FAR *lpulIpAddr;
  396.  
  397.   
  398.   socketClient = socket(PF_INET,SOCK_STREAM,0);
  399.   if (socketClient == INVALID_SOCKET)
  400.     { MsgBox( NULL,
  401.               MB_ICONSTOP | MB_OK,
  402.               "Winsock Error %s : Could not create client socket",
  403.               SocketErrorMsg(WSAGetLastError()));
  404.       WSACleanup();
  405.       return FALSE;
  406.     }                
  407.  
  408.   memset(&srv_addr,0,sizeof(struct sockaddr_in));
  409.   lstrcpy(szIpAddr,lpszServerIPAddr);
  410.   if ( (lphostent = gethostbyname(lpszServerIPAddr)) == (LPHOSTENT)0L)
  411.     { ulIpAddr = inet_addr(lpszServerIPAddr);
  412.       if ( (lphostent = gethostbyaddr(&ulIpAddr,4,PF_INET)) == (LPHOSTENT)0L)
  413.        { MsgBox( NULL,
  414.               MB_ICONSTOP | MB_OK,
  415.               "Winsock Error %s : Invalid IP Address",
  416.               SocketErrorMsg(WSAGetLastError()));
  417.          WSACleanup();
  418.          return FALSE;
  419.        }
  420.     }   
  421.   else // valid host name
  422.     { lpulIpAddr = (unsigned long FAR *) lphostent->h_addr;
  423.       ulIpAddr = *lpulIpAddr;
  424.     }  
  425.   if (ulIpAddr == INADDR_NONE)
  426.     { MsgBox( NULL,
  427.               MB_ICONSTOP | MB_OK,
  428.               "Winsock Error %s : Invalid IP Address",
  429.               SocketErrorMsg(WSAGetLastError()));
  430.       WSACleanup();
  431.       return FALSE;
  432.     }  
  433.   
  434.   srv_addr.sin_family      = AF_INET;
  435.   srv_addr.sin_addr.s_addr = ulIpAddr;
  436.   srv_addr.sin_port        = htons(WSCHESS_PORT);
  437.   if (connect(socketClient,(LPSOCKADDR)&srv_addr,sizeof(srv_addr)) == SOCKET_ERROR)
  438.     { MsgBox( NULL,
  439.               MB_ICONSTOP | MB_OK,
  440.               "Winsock Error %d : Could not connect with host\n%s",
  441.               WSAGetLastError(),
  442.               SocketErrorMsg(WSAGetLastError()));
  443.       DestroySocket(socketClient);        
  444.       WSACleanup();
  445.       return FALSE;
  446.     }
  447.   if(WSAAsyncSelect(socketClient,hwndMain,WM_SOCKET,
  448.                     FD_READ | FD_CLOSE) != 0)
  449.      { MsgBox( NULL,
  450.                MB_ICONSTOP | MB_OK,
  451.                "Winsock Error %s : Could not start client async processing",
  452.                SocketErrorMsg(WSAGetLastError()));
  453.        DestroySocket(socketClient);               
  454.        WSACleanup();
  455.        return FALSE;
  456.      }  
  457.   return TRUE;
  458. }    
  459.  
  460. void DisconnectWS(void)
  461. //---------------------
  462. { if (bHost)
  463.    { DestroySocket(socketServer);         
  464.      DestroySocket(socketListen);
  465.      bHost = bConnected = FALSE;
  466.    }
  467.   else
  468.    { DestroySocket(socketClient);
  469.      bHost = bConnected = FALSE;
  470.    }
  471.   SetWindowText(hwndMain,"Winsock Chess (Not Connected)"); 
  472.   WSACleanup();  
  473. }     
  474.  
  475. void SendMoveWS(WORD cbBytes) 
  476. //---------------------------
  477. { SOCKET socket;
  478.   int nErr;
  479.   
  480.   if (bHost)
  481.     socket = socketServer;
  482.   else
  483.     socket = socketClient;   
  484.   wPacketSize = cbBytes;  
  485.   cbSent = send(socket,moveinfo.szMove,cbBytes,0);
  486.   if (cbSent == SOCKET_ERROR)
  487.     { nErr = WSAGetLastError();
  488.       cbSent = 0;
  489.       if (nErr != WSAEWOULDBLOCK) 
  490.         { MsgBox( NULL,
  491.                MB_ICONSTOP | MB_OK,
  492.                "Winsock Error %s : Send Error",
  493.                SocketErrorMsg(WSAGetLastError()));
  494.           DestroySocket(socket);  
  495.           WSACleanup();
  496.         }  
  497.     }
  498.   if (cbSent >= wPacketSize)  
  499.     { cbSent = 0;
  500.       wPacketSize = 0;
  501.     }    
  502. }  
  503.  
  504. void GetOpponentsMoveWS(WORD cbBytes)
  505. //----------------------------------
  506. { wPacketSize = cbBytes;
  507.   bWaiting = TRUE;
  508. }  
  509.  
  510. void WaitForSocket(void)
  511. //----------------------
  512. { MSG msg;
  513.  
  514.   while (WSAIsBlocking())
  515.     while (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
  516.        DispatchMessage(&msg);
  517. }       
  518.  
  519.  
  520. BOOL CALLBACK ConfirmDlg(HWND hDlg, UINT message, WPARAM wParam, 
  521.                           LPARAM lParam)
  522. //-----------------------------------------------------------
  523. { SOCKET socket;
  524.   char *szFileName,szConfirmation[10];
  525.   LPSTR lpszGetBuf;
  526.   unsigned long ulArgp;
  527.   int cbReceived;
  528.  
  529.   switch (message) 
  530.    { case WM_INITDIALOG:     
  531.         PostMessage(hDlg,MSG_CHESS_GET,NULL,lParam);
  532.         return TRUE;
  533.         
  534.      case MSG_CHESS_GET :   
  535.        if (bHost)
  536.          socket = socketServer;
  537.        else
  538.          socket = socketClient;       
  539.        WaitForSocket();         
  540.        WSAAsyncSelect(socket,hwndMain,0,0L);
  541.        ulArgp = 0;  
  542.        ioctlsocket(socket,FIONBIO,&ulArgp);
  543.        BlockSend(socket,"COMG\r\n",7);
  544.        cbReceived = BlockReceive(socket,szConfirmation,3);
  545.        if (cbReceived != 0)
  546.          { MsgBox( NULL,
  547.                    MB_ICONSTOP | MB_OK,
  548.                   "Winsock Error %s : Receive Error",
  549.                    SocketErrorMsg(cbReceived));
  550.            DestroySocket(socket);
  551.            if (bHost)
  552.               DestroySocket(socketListen);
  553.            WSACleanup();
  554.            bHost = bConnected = FALSE;
  555.            return FALSE;
  556.          }  
  557.        if (lstrcmp(szConfirmation,"OK") != 0)
  558.          { SetDlgItemText(hDlg,IDS_WAITING,
  559.                           "Load game request rejected by opponent");  
  560.            ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);
  561.            ulArgp = 1;  
  562.            ioctlsocket(socket,FIONBIO,&ulArgp);
  563.            WSAAsyncSelect(socket,hwndMain,WM_SOCKET,
  564.                           FD_READ | FD_CLOSE);            
  565.            return TRUE;
  566.          }                 
  567.        SetDlgItemText(hDlg,IDS_WAITING,"Loading and Transmitting");  
  568.        szFileName = (char *) LOWORD((DWORD)lParam);
  569.        NewGame(hwndMain);                            
  570.        GetGame(hwndMain,szFileName);
  571.        lpszGetBuf = EncodeGame();
  572.        BlockSend(socket,lpszGetBuf,4095);
  573.        GlobalFreePtr(lpszGetBuf);
  574.        SetDlgItemText(hDlg,IDS_WAITING,"Complete");  
  575.        ulArgp = 1;  
  576.        ioctlsocket(socket,FIONBIO,&ulArgp);
  577.        WSAAsyncSelect(socket,hwndMain,WM_SOCKET,
  578.                       FD_READ | FD_CLOSE);            
  579.        ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);
  580.        return TRUE;  
  581.       
  582.      case WM_COMMAND:     
  583.         switch (wParam)
  584.          { case IDB_CONTINUE : 
  585.               EndDialog(hDlg, NULL);
  586.               return TRUE;   
  587.               
  588.          }
  589.    }
  590.  
  591.   return (FALSE); 
  592. }
  593.  
  594. void GetGameWS(void)
  595. //-------------------
  596. { char szFileName[256];
  597.   
  598.   if (GetFileName(szFileName,OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  599.                   MSG_CHESS_GET))
  600.      DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_CONFIRM),hwndMain,ConfirmDlg,
  601.                     MAKELPARAM(szFileName,0));
  602. }   
  603.  
  604. BOOL CALLBACK ConfirmNewDlg(HWND hDlg, UINT message, WPARAM wParam, 
  605.                             LPARAM lParam)
  606. //-----------------------------------------------------------
  607. { SOCKET socket;
  608.   char szConfirmation[10];
  609.   unsigned long ulArgp;
  610.   int cbReceived;
  611.   short opp;
  612.  
  613.   switch (message) 
  614.    { case WM_INITDIALOG:     
  615.         PostMessage(hDlg,MSG_CHESS_NEW,NULL,lParam);
  616.         return TRUE;
  617.         
  618.      case MSG_CHESS_NEW :   
  619.        if (bHost)
  620.          socket = socketServer;
  621.        else
  622.          socket = socketClient;
  623.        WSAAsyncSelect(socket,hwndMain,0,0L);
  624.        ulArgp = 0;  
  625.        ioctlsocket(socket,FIONBIO,&ulArgp);
  626.  
  627.        lstrcpy(moveinfo.szMove,"COMN\r\n");
  628.        BlockSend(socket,"COMN\r\n",7);  
  629.        cbReceived = BlockReceive(socket,szConfirmation,3);
  630.        if (cbReceived != 0)
  631.         { MsgBox( NULL,
  632.                   MB_ICONSTOP | MB_OK,
  633.                   "Winsock Error %s : Receive Error",
  634.                   SocketErrorMsg(cbReceived));
  635.           DestroySocket(socket);
  636.           if (bHost)
  637.             DestroySocket(socketListen);
  638.           WSACleanup();
  639.           bHost = bConnected = FALSE;
  640.           return TRUE;
  641.         }  
  642.        if (lstrcmp(szConfirmation,"OK") != 0)
  643.          { SetDlgItemText(hDlg,IDS_WAITING,
  644.                           "New game request rejected by opponent");  
  645.            ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);
  646.          }  
  647.        else        
  648.          { opp = opponent;
  649.            NewGame(hwndMain);
  650.            if (opp == black)
  651.             { computer = white;
  652.               opponent = black;
  653.               User_Move = FALSE;
  654.               flag.reverse = !flag.reverse;   
  655.               PostMessage ( hwndMain, MSG_COMPUTER_MOVE, NULL, (LPARAM)NULL);
  656.             }
  657.            else
  658.             { computer = black;
  659.               opponent = white;
  660.               User_Move = TRUE;
  661.             }  
  662.            
  663.            SetDlgItemText(hDlg,IDS_WAITING,"Complete");  
  664.            ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);  
  665.            UpdateDisplay(hwndMain,0,0,1,0);
  666.            flag.force = false;
  667.            Sdepth = 0; 
  668.          }  
  669.        WaitForSocket();      
  670.        ulArgp = 1;  
  671.        ioctlsocket(socket,FIONBIO,&ulArgp);
  672.        WSAAsyncSelect(socket,hwndMain,WM_SOCKET,
  673.                       FD_READ | FD_CLOSE);            
  674.        return TRUE;               
  675.       
  676.      case WM_COMMAND:     
  677.         switch (wParam)
  678.          { case IDB_CONTINUE : 
  679.               EndDialog(hDlg, NULL);
  680.               return TRUE;   
  681.               
  682.          }
  683.    }
  684.  
  685.   return (FALSE); 
  686. }
  687.  
  688.  
  689. void NewGameWS(void)
  690. //-------------------
  691. {
  692.   DialogBox(hInst,MAKEINTRESOURCE(IDD_CONFIRM),hwndMain,ConfirmNewDlg);
  693. }  
  694.  
  695. BOOL CALLBACK ConfirmTimeDlg(HWND hDlg, UINT message, WPARAM wParam, 
  696.                              LPARAM lParam)
  697. //-----------------------------------------------------------
  698. { SOCKET socket;
  699.   char szConfirmation[10];
  700.   unsigned long ulArgp;
  701.   int cbReceived;
  702.  
  703.   switch (message) 
  704.    { case WM_INITDIALOG:     
  705.         PostMessage(hDlg,IDM_TIMECONTROL,NULL,lParam);
  706.         return TRUE;
  707.         
  708.      case IDM_TIMECONTROL :   
  709.        if (bHost)
  710.          socket = socketServer;
  711.        else
  712.          socket = socketClient;
  713.        WSAAsyncSelect(socket,hwndMain,0,0L);
  714.        ulArgp = 0;  
  715.        ioctlsocket(socket,FIONBIO,&ulArgp);
  716.        
  717.        BlockSend(socket,"COMT\r\n",7);  
  718.        cbReceived = BlockReceive(socket,szConfirmation,3);
  719.        if (cbReceived != 0)
  720.         { MsgBox( NULL,
  721.                   MB_ICONSTOP | MB_OK,
  722.                   "Winsock Error %s : Receive Error",
  723.                   SocketErrorMsg(cbReceived));
  724.           DestroySocket(socket);
  725.           if (bHost)
  726.             DestroySocket(socketListen);
  727.           WSACleanup();
  728.           bHost = bConnected = FALSE;
  729.           return TRUE;
  730.         }  
  731.        
  732.        if (lstrcmp(szConfirmation,"OK") != 0)
  733.          { SetDlgItemText(hDlg,IDS_WAITING,
  734.                           "Set time request rejected by opponent");  
  735.            TCmoves   = oldTCmoves;
  736.            TCminutes = oldTCminutes;
  737.            if (TCflag)
  738.              SetTimeControl ();
  739.            ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);
  740.          }  
  741.        else        
  742.          { wsprintf(szConfirmation,"%3d%3d",TCmoves,TCminutes);
  743.            BlockSend(socket,szConfirmation,7);         
  744.            SetTimeControl ();
  745.            SetDlgItemText(hDlg,IDS_WAITING,"Complete");  
  746.            ShowWindow(GetDlgItem(hDlg,IDB_CONTINUE),SW_SHOW);  
  747.            UpdateDisplay(hwndMain,0,0,1,0);
  748.          }  
  749.        WaitForSocket();      
  750.        ulArgp = 1;  
  751.        ioctlsocket(socket,FIONBIO,&ulArgp);
  752.        WSAAsyncSelect(socket,hwndMain,WM_SOCKET,
  753.                       FD_READ | FD_CLOSE);            
  754.        return TRUE;               
  755.       
  756.      case WM_COMMAND:     
  757.         switch (wParam)
  758.          { case IDB_CONTINUE : 
  759.               EndDialog(hDlg, NULL);
  760.               return TRUE;   
  761.               
  762.          }
  763.    }
  764.  
  765.   return (FALSE); 
  766. }
  767.  
  768. void SetTimeWS(int id)
  769. //--------------------
  770. { oldTCmoves   = TCmoves;
  771.   oldTCminutes = TCminutes;
  772.   if ( TimeControlDialog (hwndMain, hInst, id) ) 
  773.    { TCflag = (TCmoves>1);
  774.      DialogBox(hInst,MAKEINTRESOURCE(IDD_CONFIRM),hwndMain,ConfirmTimeDlg);
  775.    }  
  776. }
  777.  
  778. void OnSocketMessage(HWND hwnd, SOCKET socket, WORD wEvent, WORD wError)
  779. //----------------------------------------------------------------------
  780. { WORD cbSnt,wSize;
  781.   int cliaddr_size, nErr;
  782.   char szCaption[50];
  783.  
  784.   switch (wEvent)
  785.    { case FD_ACCEPT :
  786.         if (! bHost) return;
  787.         if (socket != socketListen) return; // ??!!
  788.         if (wError != 0)
  789.          { MsgBox( NULL,
  790.                    MB_ICONSTOP | MB_OK,
  791.                   "Winsock Error %s : Could not accept connection (FD_ACCEPT)",
  792.                    SocketErrorMsg(wError));
  793.            
  794.            if (bHost)
  795.              { DestroySocket(socketServer);        
  796.                DestroySocket(socketListen);
  797.              }
  798.            else
  799.              DestroySocket(socketListen);   
  800.            WSACleanup();
  801.            SendMessage(hwndHostDlg,WM_CONNECTED,1,0L);
  802.            return;
  803.          }   
  804.          
  805.         // socket should == socketListen 
  806.         cliaddr_size = sizeof(struct sockaddr_in);
  807.         socketServer = accept(socket,(LPSOCKADDR)&client_addr,
  808.                               &cliaddr_size);
  809.         if (socketServer == INVALID_SOCKET)
  810.          { MsgBox( NULL,
  811.                    MB_ICONSTOP | MB_OK,
  812.                   "Winsock Error %s : Could not accept connection (accept)",
  813.                    SocketErrorMsg(WSAGetLastError()));
  814.      
  815.            WSACleanup();
  816.            SendMessage(hwndHostDlg,WM_CONNECTED,1,0L);
  817.            return;
  818.          }                                        
  819.          
  820.         //WSAAsyncSelect(socket,hwndMain,0,0); // Only one connect
  821.         
  822.         if(WSAAsyncSelect(socketServer,hwndMain,WM_SOCKET,
  823.                           FD_READ | FD_CLOSE) != 0)
  824.          { MsgBox( NULL,
  825.                    MB_ICONSTOP | MB_OK,
  826.                   "Winsock Error %s : Could not start async processing",
  827.                   SocketErrorMsg(WSAGetLastError()));
  828.            DestroySocket(socketServer);               
  829.            DestroySocket(socket);        
  830.            WSACleanup();
  831.            SendMessage(hwndHostDlg,WM_CONNECTED,1,0L);
  832.            return;
  833.          }
  834.         wsprintf((LPSTR)szCaption ,"Winsock Chess (Connected to %s)",
  835.                  (LPSTR)inet_ntoa(client_addr.sin_addr));
  836.         SetWindowText(hwndMain,szCaption);   
  837.         SendMessage(hwndHostDlg,WM_CONNECTED,0,0L); 
  838.         break; 
  839.          
  840.      case FD_WRITE :    
  841.         if ( (wPacketSize-cbSent) <= 0)
  842.           { cbSent = 0;
  843.             wPacketSize = 0;
  844.             break;
  845.           }  
  846.         cbSnt = send(socket,(moveinfo.szMove+cbSent),(wPacketSize-cbSent),0);
  847.         if (cbSnt == SOCKET_ERROR)
  848.         { nErr = WSAGetLastError();
  849.           if (nErr != WSAEWOULDBLOCK) 
  850.             { MsgBox( NULL,
  851.                       MB_ICONSTOP | MB_OK,
  852.                       "Winsock Error %s : Send Error",
  853.                       SocketErrorMsg(WSAGetLastError()));
  854.               DestroySocket(socket);  
  855.               WSACleanup();
  856.             }
  857.           else
  858.             cbSnt = 0;    
  859.         }
  860.         cbSent += cbSnt;
  861.         if (cbSent >= wPacketSize)  
  862.           { cbSent = 0;
  863.             wPacketSize = 0;
  864.           }  
  865.         break;
  866.           
  867.      case FD_READ :
  868.        wSize = wPacketSize-cbReceived;
  869.        if (wSize <= 0)
  870.          { cbReceived = 0; 
  871.            wPacketSize = 0;
  872.            break;
  873.          }  
  874.        cbSnt = recv(socket,(moveinfo.szMove+cbReceived),wSize,0);
  875.        if (cbSnt == SOCKET_ERROR)
  876.         { nErr = WSAGetLastError();
  877.           if (nErr != WSAEWOULDBLOCK) 
  878.             { MsgBox( NULL,
  879.                       MB_ICONSTOP | MB_OK,
  880.                       "Winsock Error %s : Receive Error",
  881.                       SocketErrorMsg(WSAGetLastError()));
  882.               DestroySocket(socket);  
  883.               WSACleanup();
  884.             }
  885.           else
  886.             cbSnt = 0;     
  887.         } 
  888.         cbReceived += cbSnt;
  889.         if (cbReceived >= wPacketSize)
  890.           { cbReceived = 0; 
  891.             wPacketSize = 0;
  892.             SendMessage(hwndMain,MSG_COMPUTER_MOVE,NULL,NULL);
  893.           }  
  894.         break;   
  895.         
  896.      case FD_CLOSE :
  897.        DestroySocket(socket);
  898.        bConnected = FALSE;
  899.        SetWindowText(hwndMain,"Winsock Chess (Not Connected)");
  900.        if (bHost)
  901.          { DestroySocket(socketListen);
  902.            bHost = FALSE;
  903.          }
  904.        NewGame(hwndMain);  
  905.        WSACleanup();
  906.        break;        
  907.    }      
  908.   
  909.   return;
  910. }  
  911.